package user

import (
	"context"
	"fmt"
	"github.com/spf13/cast"
	"net/http"
	"strings"
	"wms/model"

	"wms/internal/svc"
	"wms/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type ListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListLogic {
	return &ListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ListLogic) List(req *types.UserListRequest) (resp *types.UserListResponse, err error) {
	resp = new(types.UserListResponse)

	var query string
	var querys []string
	if len(strings.TrimSpace(req.Name)) > 0 {
		querys = append(querys, fmt.Sprintf("name like '%%%s%%'", strings.TrimSpace(req.Name)))
	}
	if len(strings.TrimSpace(req.Mobile)) > 0 {
		querys = append(querys, fmt.Sprintf("mobile like '%%%s%%'", strings.TrimSpace(req.Mobile)))
	}

	limit := fmt.Sprintf(" order by id desc limit %d, %d ", (req.Page-1)*req.Size, req.Size)

	if len(querys) > 0 {
		query = " where " + strings.Join(querys, " and ")
	}
	queryWithLimit := query + limit

	//1.查询分页
	users, err := l.svcCtx.UserModel.FindByPage(l.ctx, queryWithLimit)
	if err != nil {
		fmt.Printf("[Error]查询用户分页:%s\n", err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//2.查询总数
	total, err := l.svcCtx.UserModel.Count(l.ctx, query)
	if err != nil {
		fmt.Printf("[Error]查询用户总数:%s\n", err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//3.查询部门
	var departments = make(map[int64]string) //key:department_id, value:department_name
	for _, one := range users {
		department, e := l.svcCtx.DepartmentModel.FindOne(l.ctx, one.DepartmentId)
		switch e {
		case nil:
			departments[one.DepartmentId] = department.Name
		case model.ErrNotFound:
			departments[one.DepartmentId] = "部门不存在"
		default:
			fmt.Printf("[Error]查询用户[%d]部门:%s\n", one.Id, err.Error())
			resp.Code = http.StatusInternalServerError
			resp.Msg = "服务内部错误"
			return resp, nil
		}
	}
	//4.查询角色
	var userRoles = make(map[int64][]int64) //key:用户id， value:角色id切片
	for _, one := range users {
		//var roles []model.UserRole
		//roles, err = l.svcCtx.UserRoleModel.FindByPage(l.ctx, fmt.Sprintf(" where user_id=%d", one.Id))
		//if err != nil {
		//	fmt.Printf("[Error]查询用户[%d]角色:%s\n", one.Id, err.Error())
		//	resp.Code = http.StatusInternalServerError
		//	resp.Msg = "服务内部错误"
		//	return resp, nil
		//}

		//userRoles[one.Id] = make([]int64, 0)
		//for _, role := range roles {
		//	userRoles[one.Id] = append(userRoles[one.Id], role.RoleId)
		//}

		//todo:casbin roles
		var casbinRoles []string
		casbinRoles, err = l.svcCtx.Enforcer.GetRolesForUser(fmt.Sprintf("user_%d", one.Id))
		for _, casbinRole := range casbinRoles {
			userRoles[one.Id] = append(userRoles[one.Id], cast.ToInt64(strings.TrimPrefix(casbinRole, "role_")))
		}
	}

	//5.汇总
	for _, one := range users {
		resp.Data.List = append(resp.Data.List, types.User{
			Id:             one.Id,
			Name:           one.Name,
			DepartmentId:   one.DepartmentId,
			DepartmentName: departments[one.DepartmentId],
			RolesId:        userRoles[one.Id],
			Mobile:         one.Mobile,
			Status:         one.Status,
			Remark:         one.Remark,
			CreatedAt:      one.CreatedAt.Unix(),
			UpdatedAt:      one.UpdatedAt.Unix(),
		})
	}

	resp.Code = http.StatusOK
	resp.Msg = "成功"
	resp.Data.Total = total
	return resp, nil
}
